package scu.maqiang.mesh;

import java.io.FileWriter;
import java.io.IOException;
import java.util.HashSet;

import scu.maqiang.numeric.UnorderIntArray;

/**
 * һά�߶��������ε�Ԫ
 * @author ��ǿ
 *
 */
public class Mesh1L3 extends Mesh{
	
	public Mesh1L3() {
		super();
		nDim = 1;
		nPerElement = 3;
		nPerBoundary = 1;
		nEdgePerElement = 1;
		nEdgePerBoundary = 0;
		tecplotType = "FELINESEG";
		nBoundaryPerElement = 2;
		meditMeshType = new String[]{"Vertices", "Edges", "Points"};
		gmshType = new String[]{"SH", "VH", "TH"};
		gmshElementType = 8;
	}

	public void line(double a, double b, int N) {
		nv = 2 * N + 1;
		nt = N;
		nb = 2;
		initMesh0(nv, nt, nb);
		for (int i = 0; i < N + 1; i++) {
			nodes[i] = new double[] {a + (b - a) / N * i};
		}
		int count = N + 1;
		for (int i = 0; i < N; i++) {
			nodes[count++] = new double[] {a + (b - a) / N * (i + 0.5)};
		}
		for(int i = 0; i < N; i++) {
			elements[i] = new int[] {i, i + 1, i + N + 1};
		}

		boundaries[0] = new int[] {0};
		boundaryLabel[0] = 1;
		boundaries[0] = new int[] {N};
		boundaryLabel[0] = 2;
	}

	@Override
	public double[] getinteriorPointInElement(double[][] coord) {
		return new double[] {coord[2][0]};
	}

	@Override
	public double[] getinteriorPointOnBoundary(double[][] coord) {
		return new double[] {coord[0][0]};
	}

	@Override
	public int[][] getBoundarysFromElement(int i) {
		int[][] boundary = new int[nBoundaryPerElement][];
		int[] ele = elements[i];
		boundary[0] = new int[] {ele[0]};
		boundary[1] = new int[] {ele[1]};
		return boundary;
	}

	@Override
	public boolean checkMesh(double[][] coord) {
		// TODO Auto-generated method stub
		return false;
	}
	
	private void writeElements(FileWriter fw) throws IOException{
		for(int i = 0; i < nt; i++) {
			int[] idx = elements[i];
			fw.write((idx[0] + 1) + "\t" + (idx[2] + 1) + "\n");
			fw.write((idx[2] + 1) + "\t" + (idx[1] + 1) + "\n");
		}
	}
	
	@Override
	public void toTecplot(String fileName) {
		try (FileWriter fw = new FileWriter(fileName)){
			fw.write(Tecplot.meshFileString + "\n");
			fw.write(Tecplot.dimVariableString[nDim - 1] + "\n");

			fw.write(Tecplot.ZoneString(this) + "\n");
			for(int i = 0; i < nv; i++) {
				for(int j = 0; j < nDim; j++) {
					fw.write(nodes[i][j] + "\t");
				}
				fw.write("\n");
			}

			writeElements(fw);
			fw.flush();
			fw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public int getTecplotNt() {
		return 2 * nt;
	}

	@Override
	public int[][] getEdgesFromElement(int i) {
		int[][] result = new int[2][];
		int[] ele = elements[i];
		result[0] = new int[] {ele[0], ele[2]};
		result[1] = new int[] {ele[2], ele[1]};
		return result;
	}

}
